`include "defines.v"
module clint(
  input  clk,
  input  rst_n,
  input                   wen,
  input  [`PADDR_W-1:0]   addr,
  input  [`XLEN-1:0]      wdata,
  output [`XLEN-1:0]      rdata,
  // csr_ctrl_message
  input                   clintEn,
  output                  clintInterrupt
);
reg [`XLEN-1:0] mtime;
reg [`XLEN-1:0] mtimecmp;
wire selMtime = ( addr == 32'h0200_BFF8);
wire selCmp   = ( addr == 32'h0200_4000);
reg [6:0] sec;
assign rdata = selMtime ? mtime :
               selCmp   ? mtimecmp : `ZERO;

always@(posedge clk or negedge rst_n)
  if(~rst_n)
    mtimecmp <= `ZERO;
  else if(wen && selCmp)
    mtimecmp <= wdata;

always@(posedge clk or negedge rst_n)
  if(~rst_n)
    mtime <= `ZERO;
  else if(selMtime && wen)
    mtime <= wdata;
  else if(clintEn && (sec >= 99))
    mtime <= mtime + 'd1;
  
always@(posedge clk or negedge rst_n)
  if(~rst_n)
    sec <= 'd0;
  else if(sec >= 99)
    sec <= 'd0;
  else 
    sec <= sec + 1'b1;
assign clintInterrupt = clintEn && (mtime >= mtimecmp);

endmodule